package com.jhc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jhc.bo.UserSaveDetails;
import com.jhc.dto.*;
import com.jhc.entity.*;
import com.jhc.mapper.*;
import com.jhc.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jhc.utils.CheckType;
import com.jhc.utils.JHC;
import com.jhc.vo.DateVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 寝室检查记录表  服务实现类
 * </p>
 *
 * @author zfm
 * @since 2019-12-03
 */
@Service
public class IseDormInspectServiceImpl extends ServiceImpl<IseDormInspectMapper, IseDormInspect> implements IIseDormInspectService {


    @Autowired
    private IseDormInspectMapper dormInspectMapper;

    @Autowired
    private IseScheduleMapper scheduleMapper;

    @Autowired
    private UserSaveDetails userSaveDetails;

    @Autowired
    private IseInspectionMapper iseInspectionMapper;

    @Autowired
    private BacClassMapper classMapper;

    @Autowired
    private CmsTeacherMapper teacherMapper;

    @Autowired
    private IBacTermService termService;

    @Autowired
    private BacDormitoryMapper dormitoryMapper;

    @Autowired
    private IseImagesMapper imagesMapper;

    @Autowired
    private ICmsTeacherService teacherService;

    @Autowired
    private IIseInspectionService inspectionService;

    @Autowired
    private IIseScheduleService scheduleService;

    @Autowired
    private CmsUserMapper cmsUserMapper;

    @Autowired
    private ICmsUserService cmsUserService;


    /**
     * 查询当前寝室检查列表
     *
     * @param searchDto
     * @return
     */
    @Override
    public IPage<IseDormInspectViewDto> getDormInspect(IseDormInspectSearchDto searchDto) {

        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回null
        if (schedule == null){
            return new Page<>(searchDto.getCurrentPage(),searchDto.getPageSize());
        }
        //查询教学列表已检查对象id
        List<Object> itemCheckIds = inspectionService.getItemIds(nowDate,CheckType.ISEDORM.getCode());
        if (itemCheckIds.size()==0&&searchDto.getIsWrited()!=null&&searchDto.getIsWrited()){
            return new Page<>(searchDto.getCurrentPage(),searchDto.getPageSize());
        }
        //分页查询寝室列表
        Page page = new Page(searchDto.getCurrentPage(),searchDto.getPageSize());
        IPage<IseDormInspectViewDto> dormDtoPage = dormInspectMapper.selectByIseDormInspectSearchDto(page,searchDto,itemCheckIds);
        //标记是否已填写，拼接班主任和班级信息
        System.out.println("==========================");
        System.out.println("JSON:" + JSON.toJSONString(dormDtoPage));
        dormDtoPage.getRecords().stream().forEach(item ->{
            if (itemCheckIds.size()!=0&&itemCheckIds.contains(item.getId())){
                item.setIsWrited(true);
                IseInspection inspection = iseInspectionMapper.selectOne(new QueryWrapper<IseInspection>().lambda()
                        .eq(IseInspection::getItemCheckId,item.getId())
                        .eq(IseInspection::getDutyDate,JHC.toDateString(nowDate))
                        .eq(IseInspection::getCheckType,CheckType.ISEDORM.getCode()));
                item.setInspectId(inspection.getId());
            }
            List<String> list = getTeachAndClass(item.getClassTeacheres(),item.getClasses());
            if (list.size()!=0){
                item.setClasses(list.get(0));
                item.setClassTeacheres(list.get(1));
            }
            item.setWeek(schedule.getWeek());
        });
        return dormDtoPage;
    }

    /**
     * 查询寝室检查进度条
     *
     * @return
     */
    @Override
    public Map<String, Object> getProgress() {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回null
        if (schedule == null){
            return null;
        }
        //查询寝室列表数据条数
        Integer allDormInspect = dormitoryMapper.selectCount(null);
        //查询检查总表数据条数
        Integer finishDormInspect = iseInspectionMapper.selectCount(new QueryWrapper<IseInspection>().lambda()
                .eq(IseInspection::getDutyDate,JHC.toDateString(new Date()))
                .eq(IseInspection::getCheckType,CheckType.ISEDORM.getCode()));
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("allProgress",allDormInspect);
        resultMap.put("finishProgress",finishDormInspect);
        return resultMap;
    }


    /**
     * 查询当前寝室检查列表(mp方式)
     *
     * @param searchDto
     * @return
     */
    @Override
    public IPage<IseDormInspectViewDto> getDormInspect2(IseDormInspectSearchDto searchDto) {

        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回null
        if (schedule == null){
            return new Page<>(searchDto.getCurrentPage(),searchDto.getPageSize());
        }
        //查询教学列表已检查对象id
        List<Object> itemCheckIds = inspectionService.getItemIds(nowDate,20);
        //查询筛选条件
        //查询辅导员number列表
        List<Object> teacherlist = cmsUserMapper.selectObjs(new QueryWrapper<CmsUser>().lambda().select(CmsUser::getNumber)
                .like(CmsUser::getName,searchDto.getInstructorName()));
        teacherlist.add(String.valueOf(0));

        //分页查询寝室列表
        Boolean iswrited = searchDto.getIsWrited();
        Page page = new Page(searchDto.getCurrentPage(),searchDto.getPageSize());
        // TODO 错误
        IPage<BacDormitory> dormitoryIPage = dormitoryMapper.selectPage(page,new QueryWrapper<BacDormitory>().lambda()
                .in(searchDto.getInstructorName()!=null,BacDormitory::getCounselorNumber,teacherlist)
                .like(searchDto.getRoom()!=null,BacDormitory::getRoom,searchDto.getRoom())
                .like(searchDto.getBuildings()!=null,BacDormitory::getBuildingId,searchDto.getBuildings())
                .in(iswrited!=null&&iswrited,BacDormitory::getId,itemCheckIds)
                .notIn(iswrited!=null&&!iswrited,BacDormitory::getId,itemCheckIds)
                .ne(BacDormitory::getClassId,"[]"));
        System.out.println(dormitoryIPage.getRecords());
//        IPage<IseDormInspectViewDto> dormDtoPage = dormInspectMapper.selectByIseDormInspectSearchDto(page,searchDto,itemCheckIds);
        //标记是否已填写，拼接班主任和班级信息
        List<IseDormInspectViewDto> viewDtos = new ArrayList<>();
        dormitoryIPage.getRecords().stream().forEach(item ->{
            IseDormInspectViewDto viewDto = new IseDormInspectViewDto();
            BeanUtils.copyProperties(item,viewDto);
            if (itemCheckIds.contains(item.getId())){
                viewDto.setIsWrited(true);
            }
            List<String> list = getTeachAndClass(item.getClassAdviserNumber(),item.getClassId());
            viewDto.setClasses(list.get(0));
            viewDto.setClassTeacheres(list.get(1));
            viewDto.setInstructorName(cmsUserMapper.selectOne(new QueryWrapper<CmsUser>().lambda().eq(CmsUser::getNumber,viewDto.getCounselorNumber())).getName());
            viewDtos.add(viewDto);

        });
        IPage<IseDormInspectViewDto> viewDtoIPage = new Page<>();
        BeanUtils.copyProperties(dormitoryIPage,viewDtoIPage);
        viewDtoIPage.setRecords(viewDtos);
        return viewDtoIPage;
    }





    /**
     * 查询当前用户已填写的寝室检查列表
     *
     * @param searchDto
     * @return
     */
    @Override
    public IPage<FinishDormViewDto> getFinishDorm(AllDormSearchDto searchDto,Boolean type) {
        //获取当前用户名
        String username = null;
        String feedback = null;
        if (type!=null&&type){
            username = userSaveDetails.getCmsUser().getNumber();
        }
        if (type == null){
            feedback = userSaveDetails.getCmsUser().getNumber();
        }
        //获取当前学期开始和结束时间
        Date date = new Date();
        DateVo dateVo = termService.getTermDate(date);
        if (searchDto.getStartDate()==null){
            searchDto.setStartDate(dateVo.getStartDate());
        }
        if (searchDto.getEndDate()==null){
            searchDto.setEndDate(dateVo.getEndDate());
        }
        //分页查询寝室列表默认当前学期信息
        Page page = new Page(searchDto.getCurrentPage(),searchDto.getPageSize());
        IPage<FinishDormViewDto> viewDtoIPage = dormInspectMapper.selectByFinishDormSearchDto(page,searchDto,username,feedback);
        System.out.println("===========");
        System.out.println(JSON.toJSON(viewDtoIPage));
        //拼接班级信息和班主任信息
        viewDtoIPage.getRecords().stream().forEach(item ->{
            List<String> list = getTeachAndClass(item.getClassTeacheres(),item.getClasses());
            item.setClasses(list.get(0));
            item.setClassTeacheres(list.get(1));
        });
        return viewDtoIPage;
    }

    /**
     * 查询寝室检查详细信息(检查总表id查询)
     *
     * @param id
     * @return
     */
    @Override
    public DetailDormViewDto getDetailDormInspect(Long id) {
        DetailDormViewDto viewDto = new DetailDormViewDto();
        //查询寝室检查表
        IseDormInspect dormInspect = dormInspectMapper.selectOne(new QueryWrapper<IseDormInspect>().lambda()
                .eq(IseDormInspect::getInspectId,id));
        //查询检查总表
        IseInspection inspection = iseInspectionMapper.selectById(id);
        BeanUtils.copyProperties(dormInspect,viewDto);
        BeanUtils.copyProperties(inspection,viewDto);
        viewDto.setDutyNumber(inspection.getDutyTeacher());
        //查询老师表，拼接值班老师名字属性
        viewDto.setDutyName(cmsUserMapper.selectOne(new QueryWrapper<CmsUser>().lambda().eq(CmsUser::getNumber,inspection.getDutyTeacher())).getName());
        //查询寝室表
        BacDormitory dormitory = dormitoryMapper.selectById(inspection.getItemCheckId());
        BeanUtils.copyProperties(dormitory,viewDto);
        //查询老师表，拼接辅导员姓名属性
        viewDto.setInstructorName(cmsUserMapper.selectOne(new QueryWrapper<CmsUser>().lambda().eq(CmsUser::getNumber,dormitory.getCounselorNumber())).getName());
        //拼接多个班级和班主任字符串属性
        List<String> list = getTeachAndClass(dormitory.getClassAdviserNumber(),dormitory.getClassId());
        if (list.size()==0){
            viewDto.setClasses(null);
            viewDto.setClassTeacheres(null);
        }else {
            viewDto.setClasses(list.get(0));
            viewDto.setClassTeacheres(list.get(1));
        }
        //拼接多个老师字符串
        viewDto.setTeaNumbers(getTeachersStr(inspection.getTeachersNumbers()));
        viewDto.setId(dormInspect.getId());
        //查询图片
        IseImages images = imagesMapper.selectOne(new QueryWrapper<IseImages>().lambda().eq(IseImages::getInspectId,inspection.getId()));
        if (images!=null){
            viewDto.setImage(images.getAddress());
        }else {
            viewDto.setImage(null);
        }
        return viewDto;
    }

    /**
     * 获取多个教师和班级的拼接字符串
     *
     * @param teaches
     * @param classes
     * @return
     */
    @Override
    public List<String> getTeachAndClass(String teaches, String classes) {
        List<String> list = new ArrayList<>();
        List<String> stringList = (List<String>) JSON.parse(classes);
        System.out.println(stringList);
        List<Long> classIdList = JHC.toLongList(stringList);
        System.out.println(classIdList);
        if (classIdList.size()==0){
            return new ArrayList<>();
        }
        List<Object> classNameList = classMapper.selectObjs(new QueryWrapper<BacClass>().lambda().select(BacClass::getName).in(BacClass::getId,classIdList));
        list.add(StringUtils.join(classNameList,"/"));

        list.add(getTeachersStr(teaches));
        return list;
    }

    /**
     * 拼接多个老师字符串
     *
     * @param teaches
     * @return
     */
    @Override
    public String getTeachersStr(String teaches){
        //将json字符转换成number实体类列表
        List<String> teacherNumberList = (List<String>) JSON.parse(teaches);
        if (teacherNumberList.size()==0){
            return null;
        }
        //查询老师列表
        List<CmsUser> teachers = cmsUserMapper.selectList(new QueryWrapper<CmsUser>().lambda().in(CmsUser::getNumber,teacherNumberList));
        List<String> teachJoinStr = new ArrayList<>();
        //老师name和number拼接
        teachers.stream().forEach(teacher -> {
            String teachStr = JHC.addNameAndNumber(teacher.getName(),teacher.getNumber());
            teachJoinStr.add(teachStr);
        });
        return StringUtils.join(teachJoinStr,"/");
    }


    /**
     * 填写寝室反馈(检查总表id查询)
     *
     * @param feedBackAddDto
     * @return
     */
    @Override
    public Boolean addFeedbackDorm(FeedBackAddDto feedBackAddDto) {
//        IseDormInspect dormInspect = dormInspectMapper.selectById(feedBackAddDto.getId());
//        if (dormInspect == null){
//            return false;
//        }
        IseInspection inspection = iseInspectionMapper.selectById(feedBackAddDto.getId());
        if (inspection == null||inspection.getFeedbackStatus()==10){
            return false;
        }
        //获取当前登录用户编号
        String username = userSaveDetails.getCmsUser().getNumber();
        //获取责任人用户编号
        String feedbacker = dormitoryMapper.selectById(inspection.getItemCheckId()).getCounselorNumber();
        if (!username.equals(feedbacker)){
            return false;
        }

        inspection.setFeedbackStatus(20);
        inspection.setResult(feedBackAddDto.getResult());
        iseInspectionMapper.updateById(inspection);
        return true;
    }

    /**
     * 填写寝室检查
     *
     * @param addDto
     * @return
     */
    @Override
    public Map<String,Object> addDormInspect(IseDormInspectAddDto addDto) {
        Map<String,Object> trueAndMsg = new HashMap<>();
        trueAndMsg.put("success",false);
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回false
        if (schedule == null){
            return trueAndMsg;
        }
        //查询检查对象列表，查看有无记录
        BacDormitory dormitory = dormitoryMapper.selectById(addDto.getId());
        if (dormitory==null){
            return trueAndMsg;
        }
        //查询检查总表，查看有无记录
        List<IseInspection> inspectionList = inspectionService.getInspections(nowDate,addDto.getId(), CheckType.ISEDORM.getCode());
        if (inspectionList.size()>0){
            return trueAndMsg;
        }
        //遍历相关教师，校验数据
        addDto.setTeaNumbers(addDto.getTeaNumbers().stream().distinct().collect(Collectors.toList()));
        if (!cmsUserService.isUserNumberList(addDto.getTeaNumbers())){
            return trueAndMsg;
        }
        //构造检查总表插入对象
        InspectionCreateDto createDto = new InspectionCreateDto(schedule.getWeek(),nowDate,username,20);
        BeanUtils.copyProperties(addDto,createDto);
        Map<String,Object> resultMap = inspectionService.addInspection(createDto,dormitory.getCounselorNumber());
        IseInspection inspection = (IseInspection) resultMap.get("inspection");
        //构造寝室检查表插入对象
        IseDormInspect dormInspect = new IseDormInspect();
        BeanUtils.copyProperties(addDto,dormInspect);
        dormInspect.setId(null);
        dormInspect.setInspectId(inspection.getId());
        dormInspect.setImage(null);
        dormInspectMapper.insert(dormInspect);
        //构造图片插入对象
        if (addDto.getImage()!=null&&StringUtils.isNotBlank(addDto.getImage())){
            IseImages iseImages = new IseImages();
            iseImages.setAddress(addDto.getImage());
            iseImages.setInspectId(inspection.getId());
            imagesMapper.insert(iseImages);
        }
        trueAndMsg.put("msgList",resultMap.get("msgList"));
        trueAndMsg.put("success",true);
        return trueAndMsg;
    }

    /**
     * 修改寝室检查
     *
     * @param updateDto
     * @return
     */
    @Override
    public Boolean updateDormInspect(IseDormInspectUpdateDto updateDto) {
        //获取当前日期
        Date nowDate = JHC.removeTime(new Date());
        //查询值班人员
        String username = userSaveDetails.getCmsUser().getNumber();
        IseSchedule schedule = scheduleService.isSchedule(username,nowDate);
        //若不值班就返回false
        if (schedule == null){
            return false;
        }
        //查询检查总表，查看是否有记录
        IseInspection iseInspection = iseInspectionMapper.selectById(updateDto.getInspectId());
        if (iseInspection == null||!iseInspection.getDutyDate().equals(nowDate)){
            return false;
        }
        //遍历相关教师，校验数据
        updateDto.setTeaNumbers(updateDto.getTeaNumbers().stream().distinct().collect(Collectors.toList()));
        if (!cmsUserService.isUserNumberList(updateDto.getTeaNumbers())){
            return false;
        }
        //封装对象数据，更新数据
        BeanUtil.copyProperties(updateDto,iseInspection, CopyOptions.create().setIgnoreNullValue(true));
        iseInspection.setTeachersNumbers(JSON.toJSONString(updateDto.getTeaNumbers()));
        iseInspection.setDutyTeacher(username);
        iseInspection.setUpdateTime(null);
        iseInspectionMapper.updateById(iseInspection);
        //查询寝室检查
        IseDormInspect dormInspect = dormInspectMapper.selectOne(new QueryWrapper<IseDormInspect>().lambda()
                .eq(IseDormInspect::getInspectId,updateDto.getInspectId()));
        if (dormInspect == null){
            return false;
        }
        BeanUtil.copyProperties(updateDto,dormInspect,CopyOptions.create().setIgnoreNullValue(true));
        dormInspect.setUpdateTime(null);
        dormInspectMapper.updateById(dormInspect);
        //修改检查图片
        if (updateDto.getImageAddress()==null||!StringUtils.isNotBlank(updateDto.getImageAddress())){
            return true;
        }
        IseImages images = imagesMapper.selectOne(new QueryWrapper<IseImages>().lambda()
                .eq(IseImages::getInspectId,updateDto.getInspectId()));
        if (images==null){
            images = new IseImages();
            images.setAddress(updateDto.getImageAddress());
            images.setInspectId(updateDto.getInspectId());
            imagesMapper.insert(images);
            return true;
        }
        images.setAddress(updateDto.getImageAddress());
        images.setUpdateTime(null);
        imagesMapper.updateById(images);
        return true;
    }

    /**
     * 查询寝室数据分析
     *
     * @param searchDto
     * @return
     */
    @Override
    public List<AnalysisDormViewDto> getAnalysis(AnalysisSearchDto searchDto) {
        CmsUser teacher = userSaveDetails.getCmsUser();
        //查询班主任所在班级id
        List<Object> classIds = classMapper.selectObjs(new QueryWrapper<BacClass>().lambda()
                .select(BacClass::getId)
                .eq(BacClass::getAdviserNumber,teacher.getNumber()));
        if (classIds.size()==0){
            return new ArrayList<>();
        }
        //判断查询条件classId
        if (searchDto.getClassId()!=null){
            if (!classIds.contains(searchDto.getClassId())){
                return new ArrayList<>();
            }
            classIds.clear();
            classIds.add(searchDto.getClassId());
        }


        return analysisDorm(classIds,searchDto);
    }

    /**
     * 计算一个班级寝室的分析数据
     *
     * @return
     */
    @Override
    public List<AnalysisDormViewDto> analysisDorm(List<Object> classIds, AnalysisSearchDto searchDto) {
        //定义返回对象
        List<AnalysisDormViewDto> viewDtoList = new ArrayList<>();
        classIds.stream().forEach(classId -> {
            //查询班级信息
            BacClass bacClass = classMapper.selectOne(new QueryWrapper<BacClass>().lambda()
                    .eq(BacClass::getId,classId));

            AnalysisDormViewDto viewDto = new AnalysisDormViewDto();

            viewDto.setClassId(bacClass.getId());
            viewDto.setClassName(bacClass.getName());
            //查询寝室列表
            String classIdStr = "\"" + classId + "\"";
            List<Object> dormList = dormitoryMapper.selectObjs(new QueryWrapper<BacDormitory>().lambda()
                    .like(BacDormitory::getClassId,classIdStr));
            System.out.println(dormList);
            if (dormList.size()==0){
                viewDtoList.add(viewDto);
                return;
            }
            //查询检查总表
            List<IseInspection> inspectionList = inspectionService.getInspections(searchDto.getStartDate(),searchDto.getEndDate(),dormList,CheckType.ISEDORM.getCode());
            if (inspectionList.size()==0){
                viewDtoList.add(viewDto);
                return;
            }
            List<Long> inspectIds = inspectionList.stream().map(item -> item.getId()).collect(Collectors.toList());
            System.out.println(inspectIds);
            //查询寝室检查表
            List<IseDormInspect> dormInspectList = dormInspectMapper.selectList(new QueryWrapper<IseDormInspect>().lambda()
                    .in(IseDormInspect::getInspectId,inspectIds));
            System.out.println(dormInspectList);
            dormInspectList.stream().forEach(dormInspect -> {
                viewDto.addAnalysis(dormInspect);
            });
            viewDtoList.add(viewDto);
        });

        return viewDtoList;
    }


}
